#!/bin/bash

# Jar包标准更新脚本
# 使用方法: ./update_jar.sh <应用名称> <jar包路径> [环境参数] [JVM参数]
# 使用方法: ./update_jar.sh <app_name> <new_jar_path> [profile] [jvm_opts]

# 参数检查
if [ $# -lt 2 ]; then
    echo "Usage: $0 <app_name> <new_jar_path> [profile]"
    echo "Example: $0 myapp /tmp/myapp-1.0.0.jar prod"
    exit 1
fi

APP_NAME=$1
NEW_JAR_PATH=$2
PROFILE=${3:-"prod"}  # 默认为prod环境
JVM_OPTS=${4:-"-Xms512M -Xmx512M -Dfile.encoding=UTF-8"}  # 默认值

# 常量定义
APP_DIR="/opt/apps/$APP_NAME"
BACKUP_DIR="$APP_DIR/backup"
LOG_DIR="$APP_DIR/logs"
CURRENT_JAR="$APP_DIR/$APP_NAME.jar"
PID_FILE="$APP_DIR/$APP_NAME.pid"
DATE=$(date +%Y%m%d%H%M%S)

# JVM 参数配置
# JVM_OPTS="-Xms4G -Xmx4G -Xmn2G -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=512M -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai"

# 检查新jar包是否存在
if [ ! -f "$NEW_JAR_PATH" ]; then
    echo "Error: New jar file not found at $NEW_JAR_PATH"
    exit 1
fi

# 创建必要的目录
mkdir -p "$BACKUP_DIR"
mkdir -p "$LOG_DIR"

# 停止当前运行的服务
function stop_service() {
    echo "Stopping current service..."

    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p "$PID" > /dev/null; then
            kill "$PID"
            # 等待最多30秒服务停止
            for i in {1..30}; do
                if ! ps -p "$PID" > /dev/null; then
                    break
                fi
                sleep 1
            done

            # 强制停止如果仍然运行
            if ps -p "$PID" > /dev/null; then
                kill -9 "$PID"
                echo "Service forcefully stopped"
            else
                echo "Service stopped gracefully"
            fi
        fi
        rm -f "$PID_FILE"
    else
        echo "No PID file found, trying to find process by name..."
        PID=$(pgrep -f "$CURRENT_JAR")
        if [ -n "$PID" ]; then
            kill "$PID"
            echo "Service stopped by process name"
        else
            echo "No running service found"
        fi
    fi
}

# 备份当前jar包
function backup_jar() {
    echo "Backing up current jar..."
    if [ -f "$CURRENT_JAR" ]; then
        BACKUP_FILE="$BACKUP_DIR/$APP_NAME-$DATE.jar"
        cp "$CURRENT_JAR" "$BACKUP_FILE"
        echo "Backup created at $BACKUP_FILE"
    else
        echo "No current jar file found to backup"
    fi
}

# 更新jar包
function update_jar() {
    echo "Updating jar file..."
    cp "$NEW_JAR_PATH" "$CURRENT_JAR"
    chmod 755 "$CURRENT_JAR"
    echo "Jar file updated"
}

# 启动服务
function start_service() {
    echo "Starting service..."
    nohup java $JVM_OPTS -jar "$CURRENT_JAR" --spring.profiles.active=$PROFILE > "$LOG_DIR/$APP_NAME-$DATE.log" 2>&1 &
    PID=$!
    echo $PID > "$PID_FILE"
    echo "Service started with PID $PID"
}

# 检查服务状态
function check_status() {
    echo "Checking service status..."
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p "$PID" > /dev/null; then
            echo "Service is running with PID $PID"
            return 0
        else
            echo "Service is not running"
            return 1
        fi
    else
        echo "No PID file found"
        return 1
    fi
}

# 主流程
echo "Starting update process for $APP_NAME..."
stop_service
backup_jar
update_jar
start_service

# 等待5秒后检查状态
sleep 5
if check_status; then
    echo "Update completed successfully!"
else
    echo "Update completed but service failed to start. Please check logs at $LOG_DIR/$APP_NAME-$DATE.log"
    exit 1
fi

exit 0

# 示例使用
# 不传JVM参数（使用默认值）
#./update_jar.sh myapp /tmp/myapp.jar prod

# 传自定义JVM参数
#./update_jar.sh myapp /tmp/myapp.jar prod "-Xms4G -Xmx4G -XX:+UseG1GC -Duser.timezone=GMT+08"
